import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { DictDataEntity } from "@entity/system/dictData.entity";
import { ListDictDataDTO, CreateDictDataDTO, UpdateDictDataDTO } from "@dto/system/dictData.dto";
import { DownloadExcelService } from "@service/common/downloadExcel";
import { resBuild } from "@utils/resBuild";
import { checkKeyIsExist } from "@utils/serviceHelp";
import { getOperator } from "@utils";
import { RedisService } from '@midwayjs/redis';
import { RedisEnum } from "@utils/enum";
import { createClient } from 'redis';

const redisClient = createClient();
redisClient.on('error', (err) => console.error('Redis Client Error', err));
redisClient.connect();
@Provide()
export class DictDataService {
  @Inject()
  ctx: Context;

  @Inject()
  redisService: RedisService;

  @Inject()
  downloadExcelService: DownloadExcelService;

  @InjectEntityModel(DictDataEntity)
  dictDataEntity: Repository<DictDataEntity>;

  // 列表
  async list(queryParams: ListDictDataDTO) {
    const queryBuilder = this.dictDataEntity.createQueryBuilder('entity');
    if (queryParams.dictType) {
      queryBuilder.andWhere(`entity.dictType = :dictType`, { dictType: queryParams.dictType })
    }
    if (queryParams.dictLabel) {
      queryBuilder.andWhere(`entity.dictLabel like "%${queryParams.dictLabel}%"`)
    }
    if (queryParams.status) {
      queryBuilder.andWhere(`entity.status = ${queryParams.status}`)
    }
    if (queryParams.pageNum && queryParams.pageSize) {
      queryBuilder.skip((queryParams.pageNum - 1) * queryParams.pageSize).take(queryParams.pageSize)
    }
    const [rows, total] = await queryBuilder.getManyAndCount()
    return resBuild.list(rows, total)
  }

  // 添加
  async create(dictData: CreateDictDataDTO) {
    console.log('dictData', dictData)
    // 新增之前先判断是否已存在
    await checkKeyIsExist(this.dictDataEntity, 'dictLabel', dictData.dictLabel)
    const myEntity = this.dictDataEntity.create(dictData);
    myEntity.setCreateBy(getOperator(this.ctx))
    await this.dictDataEntity.save(myEntity);
    return resBuild.success()
  }

  // 删除
  async delete(dictCode: string) {
    const ids = dictCode.split(',').map(id => Number(id));
    // 删除数据库数据
    await this.dictDataEntity.delete(ids);
    // // 遍历所有 ID，删除 Redis 缓存
    // for (const id of ids) {
    //   await this.redisService.del(`dict:${id}`);
    // }
    return resBuild.success();
  }


  // 修改
  async update(dictData: UpdateDictDataDTO) {
    console.log('dictData', dictData)
    // 根据 dictCode 查找现有的记录
    const existingEntity = await this.dictDataEntity.findOne({
      where: { dictCode: dictData.dictCode },
    });
    console.log('existingEntity', existingEntity)
    if (!existingEntity) {
      return resBuild.fail('Dictionary entry not found');
    }
    // 更新现有实体的字段
    existingEntity.dictLabel = dictData.dictLabel;
    existingEntity.dictValue = dictData.dictValue;
    existingEntity.dictType = dictData.dictType;
    existingEntity.cssClass = dictData.cssClass;
    existingEntity.listClass = dictData.listClass;
    existingEntity.isDefault = dictData.isDefault;
    existingEntity.dictSort = dictData.dictSort;
    existingEntity.status = dictData.status;
    existingEntity.remark = dictData.remark;
    existingEntity.setUpdateBy(getOperator(this.ctx));
    // 保存更新后的实体
    await this.dictDataEntity.save(existingEntity);
    // 清除 Redis 缓存
    const redisKey = `${RedisEnum.SYS_DICT_KEY}${existingEntity.dictType}`
    console.log('redisKey', redisKey)
    await redisClient.del(redisKey);
    return resBuild.success();
  }



  // 详情
  async detail(dictCode: number) {
    const detailInfo = await this.dictDataEntity.findOneBy({
      dictCode,
    });
    return resBuild.data(detailInfo)
  }

  // 导出
  async export(queryParams: ListDictDataDTO) {
    const headers = [
      { label: "字典编码", prop: "dictCode", },
      { label: "字典标签", prop: "dictLabel", },
      { label: "字典键值", prop: "dictValue", },
      { label: "字典排序", prop: "dictSort", },
      { label: "状态", prop: "status", },
      { label: "备注", prop: "remark", },
      { label: "创建时间", prop: "createTime", width: 25 },
    ];
    const { rows } = await this.list(queryParams)
    return this.downloadExcelService.downloadExcel({
      headers,
      data: rows,
      sheetName: '字典数据'
    })
  }

  // 获取dictType类型的字典数据，排除 status 等于1的数据（0正常 1停用）
  async getDictDataByType(dictType: string) {
    try {
      // 尝试从Redis获取数据
      const cachedData = await this.redisService.get(`${RedisEnum.SYS_DICT_KEY}${dictType}`);

      if (cachedData) {
        console.log('Cache hit for dictType:', dictType);
        return resBuild.data(JSON.parse(cachedData));
      }

      // 缓存未命中，从数据库获取
      console.log('Cache miss for dictType:', dictType);
      const rows = await this.dictDataEntity.find({
        select: ['cssClass', 'dictValue', 'dictLabel', 'dictSort', "dictType", 'isDefault', 'status', 'listClass'],
        where: {
          dictType,
          status: '0'
        },
        order: {
          dictSort: 'ASC',
          createTime: 'DESC'
        }
      });

      // 尝试将数据存入Redis，但捕获可能的错误
      try {
        await this.redisService.set(
          `${RedisEnum.SYS_DICT_KEY}${dictType}`,
          JSON.stringify(rows),
          'EX', 3600 // 添加过期时间，例如1小时
        );
      } catch (redisError) {
        console.error('Failed to cache data in Redis:', redisError);
        // 这里可以添加降级处理逻辑，比如记录监控指标等
      }

      return resBuild.data(rows);
    } catch (error) {
      console.error('Error in getDictDataByType:', error);
      throw error; // 或者返回适当的错误响应
    }
  }
}
